Skip to content

feat(cloudflare): Auto-instrument Durable Object classes#22437

Merged
JPeer264 merged 1 commit into
jp/cloudflare-auto-instrument-withsentryfrom
jp/cloudflare-auto-instrument-durableobject
Jul 22, 2026
Merged

feat(cloudflare): Auto-instrument Durable Object classes#22437
JPeer264 merged 1 commit into
jp/cloudflare-auto-instrument-withsentryfrom
jp/cloudflare-auto-instrument-durableobject

Conversation

@JPeer264

Copy link
Copy Markdown
Member

Extend the auto-instrument transform to wrap exported Durable Object classes (those named in the wrangler durable_objects bindings) with instrumentDurableObjectWithSentry, alongside the existing default-export withSentry wrapping.

Handles the inline (export class MyDO {}) and specifier (class MyDO {}export { MyDO } / export { Foo as MyDO }) forms, leaves classes already wrapped manually untouched, and warns about configured classes it can't find in the entry (e.g. re-exports from another module, which can't be wrapped in place).

Adds a vite-autoinstrument/durableobject integration suite: a worker whose default handler and Counter Durable Object are both left unwrapped and wrapped at build time via the Vite plugin.

I also added tons of integration tests with couple of gotchas (the majority of additions are actually just tests)

@JPeer264 JPeer264 self-assigned this Jul 21, 2026
@JPeer264 JPeer264 changed the title feat(cloudflare): Auto-instrument the worker entry with withSentry feat(cloudflare): Auto-instrument Durable Object classes Jul 21, 2026
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 27.76 kB - -
@sentry/browser - with treeshaking flags 26.2 kB - -
@sentry/browser (incl. Tracing) 46.59 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 48.4 kB - -
@sentry/browser (incl. Tracing, Profiling) 51.39 kB - -
@sentry/browser (incl. Tracing, Replay) 85.83 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 75.47 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 90.56 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 103.22 kB - -
@sentry/browser (incl. Feedback) 44.95 kB - -
@sentry/browser (incl. sendFeedback) 32.56 kB - -
@sentry/browser (incl. FeedbackAsync) 37.62 kB - -
@sentry/browser (incl. Metrics) 28.84 kB - -
@sentry/browser (incl. Logs) 29.06 kB - -
@sentry/browser (incl. Metrics & Logs) 29.76 kB - -
@sentry/react 29.55 kB - -
@sentry/react (incl. Tracing) 48.87 kB - -
@sentry/vue 33.18 kB - -
@sentry/vue (incl. Tracing) 48.56 kB - -
@sentry/svelte 27.78 kB - -
CDN Bundle 30.1 kB - -
CDN Bundle (incl. Tracing) 48.48 kB - -
CDN Bundle (incl. Logs, Metrics) 31.68 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.78 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 70.94 kB - -
CDN Bundle (incl. Tracing, Replay) 85.99 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 87.31 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 91.8 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 93.07 kB - -
CDN Bundle - uncompressed 89.72 kB - -
CDN Bundle (incl. Tracing) - uncompressed 146.59 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 94.43 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 150.57 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 219.19 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 265.83 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 269.8 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 279.54 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 283.49 kB - -
@sentry/nextjs (client) 51.38 kB - -
@sentry/sveltekit (client) 47 kB - -
@sentry/core/server 80.13 kB - -
@sentry/core/browser 51.97 kB - -
@sentry/node 124.21 kB - -
@sentry/node (incl. diagnostics channel injection) 149.66 kB +0.01% +1 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 70.03 kB - -
@sentry/node - without tracing 74.38 kB - -
@sentry/aws-serverless 83.86 kB - -
@sentry/cloudflare (withSentry) - minified 196.59 kB - -
@sentry/cloudflare (withSentry) 483.84 kB - -

View base workflow run

@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-withsentry branch from e43f7dc to f03fae8 Compare July 21, 2026 15:25
@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-durableobject branch from 1d8ee57 to 6fd1b77 Compare July 21, 2026 15:25
@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-withsentry branch from f03fae8 to 9ecc3e9 Compare July 22, 2026 06:04
@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-durableobject branch from 6fd1b77 to bd69bda Compare July 22, 2026 06:04
@JPeer264
JPeer264 marked this pull request as ready for review July 22, 2026 06:07
@JPeer264
JPeer264 requested a review from a team as a code owner July 22, 2026 06:07
@JPeer264
JPeer264 requested review from andreiborza, isaacs and timfish and removed request for a team July 22, 2026 06:07
@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-withsentry branch from 9ecc3e9 to 367a3a1 Compare July 22, 2026 11:05
@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-durableobject branch from bd69bda to 1ec169c Compare July 22, 2026 11:05
Comment thread packages/cloudflare/src/vite/transform.ts
@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-withsentry branch 2 times, most recently from 2596deb to e8621d5 Compare July 22, 2026 11:25
@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-durableobject branch from 1ec169c to 4d31356 Compare July 22, 2026 11:27
@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-withsentry branch 2 times, most recently from 4b801b3 to b1f7bf1 Compare July 22, 2026 12:55
@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-durableobject branch from 4d31356 to c95ffbb Compare July 22, 2026 12:56
@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-withsentry branch from b1f7bf1 to ca8e556 Compare July 22, 2026 13:13
Extend the auto-instrument transform to wrap exported Durable Object classes
(those named in the wrangler `durable_objects` bindings) with
`instrumentDurableObjectWithSentry`, alongside the existing default-export
`withSentry` wrapping.

Handles the inline (`export class MyDO {}`) and specifier
(`class MyDO {}` … `export { MyDO }` / `export { Foo as MyDO }`) forms, leaves
classes already wrapped manually untouched, and warns about configured classes
it can't find in the entry (e.g. re-exports from another module, which can't be
wrapped in place).

Adds a `vite-autoinstrument/durableobject` integration suite: a worker whose
default handler and `Counter` Durable Object are both left unwrapped and wrapped
at build time via the Vite plugin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@JPeer264
JPeer264 force-pushed the jp/cloudflare-auto-instrument-durableobject branch from c95ffbb to 4a5d06f Compare July 22, 2026 13:13
Comment on lines +278 to +279
const localClass = localName ? state.topLevelClasses.get(localName) : undefined;
if (!localName || !localClass?.id) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Auto-instrumentation fails for Durable Object classes that are defined with an inline export and then re-exported with an alias.
Severity: HIGH

Suggested Fix

Update the collectTopLevelClasses function to traverse ExportNamedDeclaration nodes. This will allow it to discover and collect class declarations that are part of an inline export (e.g., export class Foo {}), making them available for subsequent wrapping logic when an alias is used.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: packages/cloudflare/src/vite/transform.ts#L278-L279

Potential issue: The auto-instrumentation logic fails to wrap a Durable Object class
under specific conditions. When a class is defined with an inline export (e.g., `export
class Foo {}`) and then re-exported with an alias (e.g., `export { Foo as MyDO }`), the
system fails to instrument it. The `collectTopLevelClasses` function does not recognize
inline-exported classes, so it cannot find the original class definition (`Foo`) when
processing the aliased export (`MyDO`). This results in the class not being wrapped and
a misleading warning being issued, preventing the feature from working for this common
code pattern.

@JPeer264
JPeer264 merged commit a15933e into develop Jul 22, 2026
85 checks passed
@JPeer264
JPeer264 deleted the jp/cloudflare-auto-instrument-durableobject branch July 22, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants